home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / ai / fuzzy / manual < prev    next >
Text File  |  1988-02-01  |  42KB  |  502 lines

  1.  
  2.  
  3.  
  4.                          Fuzzy Prolog  
  5.  
  6.                          User's Manual 
  7.  
  8.  
  9.  
  10.  
  11.  
  12.                                by
  13.  
  14.                 Bradley L. Richards, B. S. E. E.
  15.  
  16.                           Captain, USAF
  17.  
  18.  
  19.  
  20.                          September 1986
  21.  
  22.  
  23.  
  24.      Approved for public release; distribution is unlimited
  25.  
  26.  
  27.  
  28.                         Table of Contents
  29.  
  30.  
  31.  
  32.  
  33. Table of Contents. . . . . . . . . . . . . . . . . . . . . . .   i
  34.  
  35. Introduction . . . . . . . . . . . . . . . . . . . . . . . . .   1
  36.  
  37. Differences from Prolog  . . . . . . . . . . . . . . . . . . .   2
  38.      Lexics  . . . . . . . . . . . . . . . . . . . . . . . . .   2
  39.      Types . . . . . . . . . . . . . . . . . . . . . . . . . .   3
  40.      Operators . . . . . . . . . . . . . . . . . . . . . . . .   3
  41.      Predicates  . . . . . . . . . . . . . . . . . . . . . . .   4
  42.  
  43. Fuzzy Prolog Operators . . . . . . . . . . . . . . . . . . . .   6
  44.      Logic Operators . . . . . . . . . . . . . . . . . . . . .   6
  45.      Comparison Operators  . . . . . . . . . . . . . . . . . .   8
  46.      Arithmetic Operators  . . . . . . . . . . . . . . . . . .  11
  47.  
  48. Operation  . . . . . . . . . . . . . . . . . . . . . . . . . .  12
  49.  
  50. Syntax and Semantics . . . . . . . . . . . . . . . . . . . . .  13
  51.      Current truth value . . . . . . . . . . . . . . . . . . .  13
  52.      Search Threshold  . . . . . . . . . . . . . . . . . . . .  14
  53.      Built-in Predicates . . . . . . . . . . . . . . . . . . .  15
  54.  
  55. Formal Syntax  . . . . . . . . . . . . . . . . . . . . . . . .  26
  56.      Basic definitions . . . . . . . . . . . . . . . . . . . .  26
  57.      Lexical elements  . . . . . . . . . . . . . . . . . . . .  27
  58.      Operators . . . . . . . . . . . . . . . . . . . . . . . .  29
  59.      Syntactic elements  . . . . . . . . . . . . . . . . . . .  31
  60.  
  61. Further Information  . . . . . . . . . . . . . . . . . . . . .  32
  62.  
  63. Bibliography . . . . . . . . . . . . . . . . . . . . . . . . .  33
  64.  
  65.  
  66. Introduction
  67.  
  68. This manual describes the use of Fuzzy Prolog version 3.0.   This manual assumes that the reader is familiar with Prolog.  If  further information on Prolog is needed, refer to Programming in  Prolog [Clocksin & Mellish, 1984].  If further information on the  theory and operation of Fuzzy Prolog is desired, refer to the MS  thesis Programming in Fuzzy Logic:  Fuzzy Prolog [Richards, 1986].
  69.  
  70. Fuzzy Prolog is a dialect of Prolog based on fuzzy logic.  In  fuzzy logic truth values fall in a continuous range from false to  true, represented by numbers in the real range 0 to 1.  This is in  contrast to Prolog, which is based on predicate logic where  propositions must be either false or true.  Predicate logic is a  subalgebra of fuzzy logic, so Fuzzy Prolog encompasses all normal  Prolog operations.
  71.  
  72. Fuzzy Prolog is based on Prolog as described in [Clocksin &  Mellish, 1984], and on C-Prolog version 1.2a [Pereira].  Fuzzy Prolog  also implements many of the lexical features of Ada.  In order to  develop a Fuzzy Prolog interpreter within the scope of a thesis  effort, several Prolog features and built-in predicates were omitted.   The additions to Prolog syntax required for fuzzy logic are minimal;  Fuzzy Prolog will run normal Prolog programs with little or no  change.
  73.  
  74. Differences from Prolog
  75.  
  76. Lexics
  77.  
  78. Fuzzy Prolog follows Ada lexical rules.  This means, for  instance, that identifiers must begin with letters (in Prolog  identifiers may begin with certain nonalphabetic symbols).  In this  manual the term identifier refers to items which are valid predicate  names (i.e. names beginning with lower case letters).  Variable  names follow the same lexical rules as identifiers but begin with  capital letters.  Identifiers and variable names are not normally  case-sensitive (except for the first character, which distinguishes  between the two).  There is an alternate way of specifying  identifiers, enclosing them in double quotes, which allows them to  contain any sequence of characters.  A double quote may be inserted  by placing two consecutive double quotes (e.g. "double "" quote").   Identifiers delimited by double quotes are case sensitive.
  79.  
  80. Comment delimiters may either be the Ada double-dash '--' or  the Pascal scroll brackets '{' and '}'.  The Prolog format of '/*' and  '*/' is not supported.
  81.  
  82. Names of built-in predicates in Fuzzy Prolog are strictly  reserved by the interpreter, including those built-in predicates listed  below which are not implemented in the current version.  In Prolog,  names of built-in predicates may be redefined by the user and may  even appear as variables.
  83.  
  84. Finally, if a clause ends with an integer, there must be a space  between the integer and the period ending the clause.  Otherwise, the interpreter cannot determine whether it has reached the end of  a clause, or whether the user has forgotten to place digits to the  right of the decimal point on a floating point number.  Naturally, if  a clause ends with a floating point number there is no ambiguity,  and this restriction is not necessary.
  85.  
  86. Types
  87.  
  88. Fuzzy Prolog explicitly supports character literals (e.g. 'a') and  floating point numbers.  The addition of these explicit types may  complicate conversion of some Prolog programs.  In Prolog, if the  type of an item is deduced by elimination using predicates like var  and atom, the logic may have to be changed in Fuzzy Prolog since  more types are present.  Further changes to the predicates used to  determine types are discussed below.
  89.  
  90. Lists in Fuzzy Prolog cannot currently appear as arguments to  comparison operators.
  91.  
  92. Operators
  93.  
  94. Fuzzy Prolog has five logic operators rather than three as in  Prolog.  The new operators are the bar '|' and the hat '^'.  The  semicolon ';' is implemented as defined herein (as a "max" operation  on truth values) whereas in Prolog it represents an implicit  backtrack choice.
  95.  
  96. All comparison operators will accept arithmetic expressions on  either side (in Prolog, arithmetic expressions are allowed only on the  right-hand side of is); this has the effect of making = and is  identical.  The operators <, =<, >, and >= work with numbers, characters, and identifiers (e.g. the identifier "abc" is less then the  identifier "abd").  The is and = operators both create bindings when  one of their arguments is an uninstantiated variable.
  97.  
  98. Predicates
  99.  
  100. There are several built-in predicates which are not present in  Prolog.  Predicates fuzzy and threshold are used to manipulate the  current truth value and the search threshold; these terms are  defined in the Syntax and Semantics chapter of this manual.
  101.  
  102. The predicate atomic is different from that in Prolog.  In  Fuzzy Prolog it returns true for all types except variables and lists,  whereas in Prolog it returns true only for constants and integers.   The built-in predicate consult will accept a series of files as  arguments (e.g. consult(file1, file2, file3).
  103.  
  104. Predicate parse provides the user the ability to generate a  listing of a Fuzzy Prolog program with embedded error messages.   Predicate parse is used just like consult but rather than reading the  file into the rule base and displaying error messages to the screen it  parses the file and creates a listing file with the suffix .lst which  contains the source listing and error messages.  The parse predicate  does not read the rules into the rule base.
  105.  
  106. The following Prolog predicates are not currently implemented  in Fuzzy Prolog:
  107.  
  108.  =..       clause    display   functor   get       get0
  109.  
  110. name      nodebug   nospy     op        org       reconsult
  111.  
  112. see       seeing    seen      spy       tell      telling
  113.  
  114. told
  115.  
  116.                     
  117.  
  118. Fuzzy Prolog Operators
  119.  
  120. Fuzzy Prolog uses essentially the same operators as Prolog.   Fuzzy Prolog includes two additional logic operators and adds  flexibility to the comparison operators.  In all cases except the ';'  Fuzzy Prolog operators produce results identical to Prolog operators,  though the reverse is not true.  The ';' in Fuzzy Prolog performs a  Fuzzy-OR of its operands, whereas in Prolog it represents an  implicit backtrack choice.
  121.  
  122. Logic Operators      The major functional difference between Fuzzy Prolog and  ordinary Prolog is that Fuzzy Prolog is based on fuzzy logic rather  than predicate logic.  In fuzzy logic truth values are in the real  range 0 to 1 rather than just false or true.  Also, fuzzy logic uses  five logic operators rather than the three (AND, OR, and NOT) used  in predicate logic.  These operators are the fuzzy AND (f-AND or  ','), fuzzy OR (f-OR or ';'), probability AND (p-AND or '^'),  probability OR (p-OR or '|'), and complement (NOT or 'not').  The  three of these which use Prolog operator symbols (f-AND, f-OR, and  complement) all produce the same results as Prolog operators when  given nonfuzzy operands (i.e. 0 and 1).
  123.  
  124. The precedence of the logic operators is
  125.  
  126. ; -- 254       , -- 253         -- 252       ^ -- 251
  127.  
  128. not -- 60
  129.  
  130. where lower precedence indicates earlier execution.
  131.  
  132. The f-AND is defined as
  133.  
  134.  a f-AND b  =  min(a, b).
  135.  
  136. When used with nonfuzzy values, this operator produces the truth  table
  137.  
  138.                     0    1                                                            0       0    0                                                1       0    1                          
  139.  
  140. which is the same as the truth table for the predicate logic AND.   Similarly, the f-OR and NOT are defined as
  141.  
  142.  a f-OR b  =  max(a, b),
  143.  
  144.     and
  145.  
  146. NOT a  = 1 - a
  147.  
  148. respectively, and give the same results for nonfuzzy operands as do  predicate logic operators.
  149.  
  150. The p-AND and p-OR are defined as
  151.  
  152.  a p-AND b  =  a * b,
  153.  
  154.     and
  155.  
  156. a p-OR b  =  a + b - a * b.
  157.  
  158. These operators have no equivalent in Prolog.  The p-AND  represents the probability that two independent events a and b will  both occur.  The p-OR represents the probability that either or both  of the events will occur.  These operators are used in the same way  as the normal Prolog operators; e. g.
  159.  
  160.  scary(Movie) :- gory(Movie) ^ tense(Movie) | eerie(Movie).
  161.  
  162. Comparison Operators
  163.  
  164. Fuzzy Prolog has the same set of comparison operators as  Prolog, although they are defined somewhat differently.  In all cases  the Fuzzy Prolog operators will work with a program written for  Prolog.  The reverse, however, is not true.  The most notable  difference is that arithmetic operations may be carried out on either  side of any comparison operator.  This means that the "is" operator  is no different from the "=" operator.  The precedence of the  comparison operators is
  165.  
  166.    = -- 40       \= -- 40       == -- 40      \== -- 40
  167.  
  168.  < -- 40       =< -- 40       >= -- 40        > -- 40
  169.  
  170. is -- 40
  171.  
  172. Since lower precedence indicates earlier execution, comparison  operators will be executed before logic operators.  When comparison  operators succeed they return a truth value of 1.  When they do not  succeed they cause failure and backtracking.
  173.  
  174.                      
  175.  
  176.  Equal '='.  The equal operator compares its operands and  returns true if they have (or are bound to) the same value.  If they  have different values it returns false.  If either or both of the  operands is uninstantiated then the two operands are bound together  and equal returns true.
  177.  
  178. Not equal '\='.  The "not equal" operator is the complement of  the equal operator.  If the two operands have the same value it  returns false.  If they have different values it returns true.  If one  or both of the operands is uninstantiated (and hence they would be  "equal"), it returns false.  "Not equal" does not affect any variable  bindings.
  179.  
  180. Equality '=='.  The equality operator returns true if its  operands have the same value, and false if they do not.  If either  operand is uninstantiated then, unless the operands are the same  uninstantiated variable, the operands do not have the same value and  equality returns false.  If the operands are the same uninstantiated  variable then equality returns true.  Equality does not affect any  variable bindings.
  181.  
  182. Not equality '\=='.  The "not equality" operator is the  complement of the equality operator.  If the operands are equal it  returns false.  If they are different it returns true.  If either  operand is uninstantiated it returns true, unless the operands are  the same uninstantiated variable in which case it returns false.  This  operator does not affect variable bindings.
  183.  
  184. Less or equal '=<'.  This operator works on numbers,  characters, and identifiers.  It returns true if the left-hand operand  is less than or equal to the right-hand operand, and false otherwise. 
  185.  
  186.                        
  187.  
  188. For characters and identifiers this represents a comparison of the  ordinal value of the characters within the character set.  This  operator does not affect variable bindings.
  189.  
  190. Greater or equal '>='.  This operator works on numbers,  characters, and identifiers.  It returns true if the left-hand operand  is greater than or equal to the right-hand operand, and false  otherwise.  For characters and identifiers this represents a  comparison of the ordinal value of the characters within the  character set.  This operator does not affect variable bindings.
  191.  
  192. Less than '<'.  This operator works on numbers, characters, and  identifiers.  It returns true if the left-hand operand is less than the  right-hand operand, and false otherwise.  For characters and  identifiers this represents a comparison of the ordinal value of the  characters within the character set.  This operator does not affect  variable bindings.
  193.  
  194. Greater than '>'.  This operator works on numbers, characters,  and identifiers.  It returns true if the left-hand operand is greater  than the right-hand operand, and false otherwise.  For characters  and identifiers this represents a comparison of the ordinal value of  the characters within the character set.  This operator does not  affect variable bindings.
  195.  
  196. Arithmetic comparison 'is'.  In Fuzzy Prolog this operator is  identical to the "equal" comparison operator.  In Prolog this operator  represents the only allowable time to perform arithmetic calculations  for a comparison.  In Fuzzy Prolog, arithmetic expressions are  allowed as operands on either side of any comparison operator.
  197.  
  198. Arithmetic Operators
  199.  
  200. Fuzzy Prolog implements five arithmetic operators:  +, -, *, /,  and mod.  Operands for these operators must be numeric.  They may  not be uninstantiated variables.  The following predicates are  examples of legal usage:
  201.  
  202.  X is 7 * (3 + 4) mod 8   (X will be bound to 1)
  203.  
  204. 4 * Y  \==  8       (Y must have a value when '*' is executed)
  205.  
  206. 7.0  =<  9.3
  207.  
  208. 3 + 4  =  X         (X will be bound to 7)
  209.  
  210. The precedence of the arithmetic operators is
  211.  
  212.    + -- 31        - -- 31        * -- 21        / -- 21
  213.  
  214. mod -- 11
  215.  
  216. where lower precedence indicates earlier execution.  Arithmetic  operators are executed before comparison or logic operators.  The  definition of the arithmetic operators is self-evident.
  217.  
  218. Operation
  219.  
  220.  Fuzzy Prolog was written in Ada under the Verdix Ada  Development System running on a VAX 11/785 with Berkeley UNIX  4.2 BSD.  For source or object code contact the Air Force Institute  of Technology, Department of Electrical and Computer Engineering,  Wright-Patterson Air Force Base, Ohio 45433.
  221.  
  222. The interpreter is invoked by typing fuzzy.  It will initialize  itself, display the current version number, and display the normal  '?-' prompt.  From this point using the Fuzzy Prolog interpreter is  the same as using a Prolog interpreter; the user enters goals to be  satisfied and Fuzzy Prolog attempts to resolve the goals within its  rule base.  As in Prolog, all user inputs must be terminated by a  period.  To leave the interpreter the user enters the single goal  "halt."
  223.  
  224. Syntax and Semantics
  225.  
  226. Fuzzy Prolog resolves goals by using resolution and unification,  just as Prolog does.  In Prolog goals either succeed or fail; if they  succeed resolution continues and if they fail backtracking occurs and  another path in the search tree is tried.  In Fuzzy Prolog, however,  goals may return values other than false and true and the search  process must account for this.  To manage fuzzy truth values, the  interpreter internally maintains two variables:  the current truth  value and the search threshold.
  227.  
  228. Current truth value
  229.  
  230. The current truth value at any point is the cumulative value of  the predicates that have been resolved and the logic operators that  have been executed.  The truth value is initially set to 1.  For  example, if the user provides the goal a and the rule base contains  the clause
  231.  
  232.  a :- b, c.
  233.  
  234. the truth value begins at 1.  If predicate b is resolved and returns  the truth value 0.7, 0.7 will become the current truth value.  If  predicate c is resolved and returns the truth value 0.5 then the  current truth value will become 0.5 since the comma represents the  f-AND operation (which is defined as min(0.7, 0,5)).  Since all  predicates have now been resolved, this value will be returned as the certainty of the solution Fuzzy Prolog has found through this  chain of resolution.
  235.  
  236. In some cases determining the current truth value may be less  straightforward.  In the clause
  237.  
  238.  a :- b, c ^ d.
  239.  
  240. the precedence of the p-AND operator ('^') dictates that it be  executed before the f-AND operator (','), even though the predicates  are resolved left-to-right.  As a result, after resolving predicate c  the truth values of b and c cannot be combined; their truth values  must be separately maintained until after d has been resolved.  In  cases like this, the most recently developed truth value (here the  truth value of c) is the current truth value.
  241.  
  242. The current truth value may be accessed and manipulated via  the built-in predicate fuzzy, which is defined later in this chapter.
  243.  
  244. Search Threshold
  245.  
  246. The search threshold in Fuzzy Prolog defines a criterion for  the success or failure of searches.  In Prolog backtracking is  initiated when an attempted resolution fails.  In Fuzzy Prolog  backtracking is also initiated when the current truth value falls  below a predefined search threshold.
  247.  
  248. The search threshold defaults to 0.1 and may range from 0 to  1.  It is accessed and manipulated by the built-in predicate  threshold.
  249.  
  250.  
  251. Built-in Predicates
  252.  
  253. Fuzzy Prolog includes the following built-in predicates:
  254.  
  255.  !         asserta   assertz   atom      atomic    call
  256.  
  257. consult   fail      float     fuzzy     integer   listing
  258.  
  259. ln        log       nl        nonvar    notrace   number
  260.  
  261. parse     put       read      repeat    reset     retract
  262.  
  263. tab       threshold trace     true      var       write
  264.  
  265. Note that halt, which is entered by the user to terminate Fuzzy  Prolog, is neither a built-in predicate nor a reserved word.
  266.  
  267. Cut '!'.  The cut in Fuzzy Prolog is identical to the cut in  ordinary Prolog.  It is used to limit backtracking by committing  Prolog to all choices made in the current clause up to the point  where the cut occurs.
  268.  
  269. asserta.  The asserta predicate is used to add facts dynamically  to the data base.  It accepts one or two arguments:  a functor  which becomes the head of the fact and a fuzzy truth value which  becomes the tail (a functor is an identifier which may optionally be  followed by an argument list).  If the second argument is not  specified the fuzzy truth value defaults to 1.  For example, if
  270.  
  271.  asserta( alpha(A,B), 0.6 )
  272.  
  273. is encountered during program execution, it will add the fact
  274.  
  275.  alpha(A,B) :- fuzzy(0.6).
  276.  
  277. to the data base.  Facts added with asserta are inserted in the data  base before any other clauses with the same name.
  278.  
  279. assertz.  Predicate assertz is identical to asserta except that it  adds facts after any other clauses with the same name.
  280.  
  281. atom.  This predicate requires a single argument.  It succeeds  (i.e. returns a truth value of 1) if its argument is an identifier (i.e.  a valid predicate name).  For example, atom will return true in all  the following clauses:
  282.  
  283.  atom(alpha)  atom(alpha(X, 13))  atom("hi there")  A = alpha, atom(A)
  284.  
  285. It will fail in the following examples:
  286.  
  287.  atom(A)             (X is uninstantiated)  atom(13)  atom('c')
  288.  
  289. atomic.  This predicate requires a single argument, and will  return a truth value of 1 if that item is an identifier, character  literal, integer number, or floating point number. It will fail if its  argument is a list or an uninstantiated variable.
  290.  
  291. call.  Predicate call takes a single argument, which must be a  functor.  It causes Fuzzy Prolog to resolve its argument as if that  argument appeared in place of the call predicate.  For example, the  following statements are completely equivalent:                      
  292.  
  293.  alpha(X,Y)  call(alpha(X,Y))
  294.  
  295. The call predicate is generally used to call functors which have been  bound to a variable, e.g. call(X) where X is bound to some functor.   Note that variables appearing in a functor are lexically scoped (i.e.  their values are taken from the clause in which the functor is  defined).  For example, in the program
  296.  
  297.  a :- X = 3, b(alpha(X)).  b(What) :- X = 4, call(What).  alpha(Num) :- write(Num), nl.
  298.  
  299. a call to a will write the number 3--not the number 4.
  300.  
  301. consult.  The consult predicate is used to read in one or more  files of Fuzzy Prolog clauses.  These clauses are added to the  beginning of the rule base.  Filenames are given as constants, e.g.
  302.  
  303.  consult(file1, file2, file3).
  304.  
  305. Fuzzy Prolog translates identifiers to all upper case, so the file  names given above would actually refer to FILE1, FILE2, and FILE3.   If this is not desirable, or if the file names contain characters not  normally allowed in identifiers, then the file names should be  enclosed in double quotes.  File names in quotes may be pathnames.
  306.  
  307. fail.  Predicate fail causes immediate failure and backtracking.
  308.  
  309. float.  Predicate float takes a single argument.  It succeeds if  its argument is a floating point number, and fails otherwise.
  310.  
  311.  fuzzy.  The built-in predicate fuzzy sets and accesses fuzzy  truth values.  It may appear anywhere as an antecedent to a clause.   It accepts a single argument, which must either have a floating  point value or be an uninstantiated variable.  The clauses
  312.  
  313.  alpha :- fuzzy(0.5).  beta :- alpha, fuzzy(X).  delta :- X = 0.3 | fuzzy(X).
  314.  
  315. all show legal uses of fuzzy.
  316.  
  317. If the argument to fuzzy is an uninstantiated variable, the  variable is instantiated to the current truth value.  Additionally,  fuzzy returns the current truth value as the truth value of its  resolution.  This means that, if fuzzy is connected to other  predicates with the f-AND or the f-OR operator, it will not change  the current truth value (since min(a,a) = a and max(a,a) = a).   Calling fuzzy with a variable allows a program to access the current  truth value and use it in calculations or to direct future actions.
  318.  
  319. If the argument to fuzzy has a floating point value, fuzzy  returns this value as the truth value of its resolution.  This is the  only way of introducing fuzzy truth values into the resolution  process since predicate resolution and the comparison operators  always either succeed or fail.  If fuzzy is the only antecedent in a  clause then the clause is a special type of fact; i.e. a fact with a  fuzzy truth value.  For example
  320.  
  321.  alpha :- fuzzy(0.7).
  322.  
  323. causes the predicate alpha to have a fuzzy truth value of 0.7.
  324.  
  325. If fuzzy is called with an uninstantiated variable, it sets that  variable to the current truth value, and returns with its own truth  value set to the current truth value.  Note that the current truth  value depends heavily on the order of evaluation of the surrounding  operators as determined by operator precedence or parentheses.  For  example, in the clause
  326.  
  327.  alpha :- fuzzy(0.7), true ^ fuzzy(X).
  328.  
  329. fuzzy will set X to 1.0 since that is the value returned by "true"  and the precedence of the p-AND causes it to be executed before  the f-AND.  Similarly, if fuzzy is within parentheses then its truth  value will only be taken from other predicates and operators in the  parentheses.  The following clause will instantiate X to the lower  value of "b" or "c":
  330.  
  331.  f :- a, (b, c, fuzzy(X), d), e.
  332.  
  333. On the other hand,
  334.  
  335.  alpha :- beta, delta, fuzzy(X), gamma.
  336.  
  337. will set X to the lesser of the values returned by beta and delta,  since normal execution is left to right and the precedence of the  operators does not interfere with this.
  338.  
  339.  integer.  Predicate integer takes a single argument.  It  succeeds if its argument is an integer number, and fails otherwise.
  340.  
  341. listing.  This predicate takes a single functor as its argument.   It displays a list of all clauses in the rule base which have as their  head a predicate with the same name as the functor it received as  an argument.  The number of arguments the functor has is  irrelevant.  The listing produced has a somewhat different format  from user-generated source code.
  342.  
  343. ln.  Predicate ln takes two arguments.  The first argument is a  number and the second argument is the natural logarithm of that  number.  Either argument may be uninstantiated; this predicate will  therefore perform both natural logarithms and exponentiation.
  344.  
  345. log.  Predicate log takes two arguments.  The first argument is  a number and the second argument is the base 10 logarithm of that  number.  Either argument may be uninstantiated; this predicate will  therefore perform both logarithms and exponentiation.
  346.  
  347. nl.  The "nl" predicate generates a new line by sending an end-  of-line character (carriage return) to the current output device.
  348.  
  349. nonvar.  Predicate nonvar takes a single argument and returns  true if that argument is anything except an uninstantiated variable.   If the argument is an uninstantiated variable nonvar fails.
  350.  
  351. notrace.  Notrace turns off the trace feature.  See "trace" for  further information.
  352.  
  353. number.  This predicate accepts a single argument.  It returns  true if that argument is either an integer or a floating point  number, and fails otherwise.
  354.  
  355.  parse.  Predicate parse is used like consult.  However, rather  than reading a Fuzzy Prolog program into the rule base, parse  generates a listing file.  This is useful when initially writing a  program since error messages are embedded in the listing file rather  than displayed to the screen.  The listing file has the same name as  the source file plus the suffix ".lst".  Parse does not add rules to  the data base.
  356.  
  357. put.  Predicate put takes a single argument, which must be an  integer in the ordinal range of the character set.  It writes the  corresponding character to the current output device.  For example,  put(65) would print an 'A'.
  358.  
  359. read.  Read requires one argument.  It prompts the user for  input, and attempts to unify its argument with the next term read  from the keyboard.  If its argument is an uninstantiated variable it  will be set to the term read from the keyboard; otherwise it will  simply be matched against it.  If unification succeeds then read  returns true, otherwise it returns false.
  360.  
  361. repeat.  This predicate is used to generate multiple solutions  through backtracking.  Most built-in predicates will fail when  backtracking attempts to resatisfy them.  This predicate will succeed  any number of times.  Hence, it represents an infinite loop which  may only be exited by the cut.
  362.  
  363. reset.  Completely erases and reinitialized the rule base.
  364.  
  365. retract.  The retract predicate takes a functor as its argument  and removes from the rule base the first clause whose head unifies  with this functor (unification includes the functor arguments).  It is  the counterpart of asserta and assertz.
  366.  
  367.  tab.  This predicate requires a single argument which must be  an integer.  It prints the requested number of spaces to the current  output device.
  368.  
  369. threshold.   The built-in predicate threshold sets and accesses  search threshold values.  If, during resolution, the current truth  value falls below the current search threshold, resolution fails and  backtracking occurs.  Predicate threshold may appear anywhere as  an antecedent to a clause, and the threshold it defines takes effect  from that point in the clause (resolution proceeds strictly left-to-  right within a clause).  It accepts a single argument, which must  either have a floating point value or be an uninstantiated variable.   The clauses
  370.  
  371.  alpha :- threshold(0.5).  beta :- alpha, threshold(X).  delta :- X = 0.3 | threshold(X).
  372.  
  373. all show legal uses of threshold.  This predicate always returns with  its own truth value of 1.
  374.  
  375. In other words, If the user wishes to continue processing as  long as the truth value remains 0.5 or higher, then threshold should  be called with a value of 0.5.  If a clause needs to know what the  current threshold is, it calls threshold with an uninstantiated  variable.
  376.  
  377. Predicate threshold defines a local level of success, not a  global one.  When a clause defines a threshold, this threshold  applies to the remainder of that clause, and to any other clauses  which it invokes through resolution.  The threshold will not affect higher-level clauses.  This may be likened to the visibility rules for  variables in Pascal or Ada, where a variable is visible to the  procedure in which it is defined and all its subprocedures but is not  visible outside the procedure.  For instance, if rule base contains
  378.  
  379.  alpha :- beta, delta.  beta :- threshold(0.5), gamma.  gamma.
  380.  
  381. and the user introduces the goal alpha, the threshold set in beta  will apply to beta and gamma (since gamma is a goal introduced by  beta).  However, the threshold will not propagate upward into alpha  and delta.
  382.  
  383. Limiting search thresholds to local effects allows a predicate to  control backtracking for its operations without causing unexpected  side-effects for higher level predicates (which have no insight into  its workings).  If the threshold were global, then a predicate might  find its searches failing because its search threshold was altered by  some predicate which it called.
  384.  
  385. If a clause does not define its own threshold, its threshold will  be taken to be the one currently in effect.  If it does define one,  then the threshold it defines will hold for it and all predicates  which it calls (unless those predicates in turn define their own local  thresholds).  For example, the rules
  386.  
  387.  a :- threshold(0.5), b, c.  b :- threshold(0.7), d.  c.  d.
  388.  
  389. will result in clauses a and c using a threshold of 0.5.  However, b  defines its own threshold of 0.7, so b and d will use this value.
  390.  
  391. If threshold is called with an uninstantiated variable, it sets  the variable to the value of the threshold currently in effect.  This  allows clauses to base their threshold on the one in effect when  they are called.
  392.  
  393. trace.  This predicate turns on the trace mode.  Each time a  predicate is called, trace will print the current truth value and the  values of all arguments on entry to the predicate.  When the  predicate returns, trace prints its truth value, the values of all its  arguments, and the new current truth value.  Trace cannot intercept  the actions of comparison operators.
  394.  
  395. After each trace output, Fuzzy Prolog waits for the user to  enter a trace command.  Hitting a carriage return will continue  program execution.  A question mark will print a menu of valid  trace commands.  The valid commands are:
  396.  
  397.     return, space, or Continue -- continue execution                          Abort -- abort current proof                       Bindings -- print variable bindings                           Fail -- fail current goal                          Goals -- print goal tree                      Help or ? -- print help menu                        Notrace -- turn off trace mode                          Truth -- print current truth/threshold
  398.  
  399. Commands may be selected by entering just their first character.
  400.  
  401. true.  This predicate returns a truth value of 1.0.  This  predicate is never needed, but it occasionally helps make a program  more readable.
  402.  
  403.  var.  Predicate var takes a single argument.  It returns true if  this argument is an uninstantiated variable, and fails otherwise.
  404.  
  405. write.  Prints the value of its single argument to the current  output device.
  406.  
  407. Formal Syntax
  408.  
  409. Fuzzy Prolog syntax is based on Prolog as described in  [Clocksin & Mellish, 1984].  Fuzzy Prolog also implements many of  the lexical features of Ada.  The additions to Prolog syntax required  for fuzzy logic are minimal; Fuzzy Prolog will run normal Prolog  programs with little change.
  410.  
  411. The following paragraphs define the syntax of Fuzzy Prolog in  Backus-Naur form (BNF), beginning with basic lexical elements and  building up to the syntax of clauses.  The features of Fuzzy Prolog  are discussed at each step.
  412.  
  413. Basic definitions
  414.  
  415. Identifiers in Fuzzy Prolog consist of letters, numbers, and  underlines.  Numbers may contain digits or underlines; which digits  are valid depends on the base of the number.
  416.  
  417.  upper_case_letter  ::=  A   B   C . . . W   X   Y   Z  lower_case_letter  ::=  a   b   c . . . w   x   y   z  num_digit  ::=  0   1   2   3 . . . 7   8   9  alpha_digit  ::=  A   a   B   b . . . E   e   F   f  underline  ::=  _
  418.  
  419. digit  ::=  num_digit   alpha_digit  letter  ::=  upper_case_letter   lower_case_letter  name_character  ::=  letter   digit   underline  number_character  ::=  digit   underline
  420.  
  421. line_comment  ::=  -- {character} new_line  block_comment  ::=  '{' {character} '}'
  422.  
  423.  Note that the comment delimiters in Fuzzy Prolog are different  from those in Prolog.  In Fuzzy Prolog comments may be placed at  the end of a line by using the Ada double-dash, or blocks of  comments may be delimited by the scroll-brackets.  Block comment  delimiters may be nested; this may arise, for example, if an entire  block of code is commented out.  The Prolog delimiters '/*' and '*/'  are not supported.
  424.  
  425. Lexical elements
  426.  
  427. The lexical rules below define Fuzzy Prolog identifiers,  variables, numbers, and character literals.  These basic elements can  be used to build lists.  Any of these items including lists may appear  as arguments to predicates.
  428.  
  429.  anon_variable  ::=  underline  variable_name  ::=  upper_case_letter {name_character}  variable  ::=  variable_name   non_variable  identifier  ::=  lower_case_letter {name_character}                                        " character {character} "
  430.  
  431. integer  ::=  digit {number_character}  real  ::=  integer . integer  basic_number  ::=  integer   real  based_number  ::=  integer # basic_number   #number  ::=  basic_number   based_number
  432.  
  433. character_literal  ::=  ' character '
  434.  
  435. constant  ::=  identifier [ ( argument {, arguments} ) ]                     number   character_literal  term  ::=  variable   constant  term  ::=  ( term {arithmetic_operator term} )  item  ::=  variable   constant   list  list  ::=  '[' [ item { , item } ['|' item] ] ']'  argument  ::=  item   list
  436.  
  437.  Identifiers are sequences of letters, digits, and underlines which  begin with a lower-case letter.  Underlines may not begin or end an  identifier or be adjacent to each other.  Identifiers may be names of  built-in predicates (reserved words) or user-defined names.   Variables are sequences of letters, digits, and underlines which begin  with an upper-case letter, except for the anonymous variable (where  the underline is the only character present).  Case is not normally  significant in identifiers except for the first letter, which determines  whether or not an identifier is a variable.  However, an identifier  can be specified in double-quotes.  Identifiers specified in this way  can contain any sequence of characters, which will be used exactly  as specified (i.e. case will be significant).  To embed a double quote,  two consecutive double quotes are used (e.g. "double "" quote").
  438.  
  439. Numbers may be integer or floating point.  Floating point  numbers must contain a decimal point with at least one digit on  each side.  Numbers may be specified in any base between 2 and 16  inclusive by using the based notation; the base itself is always given  in base 10.  Numbers may contain underlines, but the underlines  must separate digits; they cannot begin or end the number or appear  next to the base character ('#') or the decimal point.  The digits  valid in a number depend on its base.  If base is not specified, the  number is assumed to be decimal (base 10).
  440.  
  441. Character literals are single characters enclosed in single  quotes.  Lists are ordered collections of items (possibly including  other lists).  The beginning and ending of a list are marked by  square brackets ('[' and ']').  Elements within a list are separated by commas, except for the final element which may be preceded by a  vertical bar ('|') and is then referred to as the tail of the list.
  442.  
  443. Prolog defines a special element called a functor, which is a  predicate complete with arguments (e.g. in asserta(alpha(A,B)) both  asserta and alpha are functors).  In Fuzzy Prolog no distinction is  drawn between identifiers and identifiers with arguments, so functors  are valid anywhere identifiers are valid.  When a functor is passed  as an argument to another predicate, it is important to remember  that any variables it contains are lexically scoped.  See the  discussion under the call predicate for more information.
  444.  
  445. Arguments to predicates may consist of any of the items  defined in this section.
  446.  
  447. The Fuzzy Prolog parser reserves the names of all built-in  predicates including those which are not implemented.  This allows  easy addition of these predicates at a later time, and avoids  confusion by preventing the user from choosing identifier names  which conflict with predicates normally defined in Prolog  interpreters.
  448.  
  449. Operators
  450.  
  451. The following operators are implemented in Fuzzy Prolog with  the precedence shown (lower precedence indicates earlier execution):
  452.  
  453. ; -- 254       , -- 253         -- 252       ^ -- 251
  454.  
  455. not -- 60        = -- 40       \= -- 40       == -- 40
  456.  
  457. \== -- 40        < -- 40       =< -- 40       >= -- 40
  458.  
  459.  > -- 40       is -- 40        - -- 31        + -- 31
  460.  
  461.  * -- 21        / -- 21      mod -- 11
  462.  
  463. These operators are broken into three classes as follows:
  464.  
  465.  arithmetic_operator  ::=  +   -   *   /   mod  comparison_operator  ::=  =   \=   ==   \==   =<   >=                                                 <   >   is  logic_operator  ::=  ,   ;   ^       not
  466.  
  467.  Arithmetic operators may only be used to calculate the  operands for comparison operators.  Arithmetic operators may appear  on either side of any comparison operator; however, all arguments to  arithmetic operators must have values (they cannot be uninstantiated  variables).  This allows more flexibility than normal Prolog, where  arithmetic expressions may only appear on the right-hand side of the  is operator.
  468.  
  469. Since performing arithmetic matching is the only distinguishing  feature of is in Prolog, the is operator in Fuzzy Prolog is  functionally identical to the '=' operator.  In Fuzzy Prolog, any  comparison operator can compare any two items and generate a  truth value of 0 or 1 depending on the particular matching function  being used (for specific definitions of the comparison operators see  appendix D).  The is and = operators will create a variable binding  when one of their operands is an uninstantiated variable, just as in  Prolog.
  470.  
  471.  Logic operators operate on truth values, and the result of a  logic operator is itself a truth value.  The logic operators implement  the operations of fuzzy logic as defined in chapter II, where ';' is  the f-OR, ',' is the f-AND, '|' is the p-OR, '^' is the p-AND, and  not is the NOT operation.
  472.  
  473. Fuzzy Prolog does not support user-defined operators.
  474.  
  475. Syntactic elements
  476.  
  477. Fuzzy Prolog clauses are built of predicates joined by logic  operators.  Predicates may be user defined identifiers, built-in  predicates (see above), or any operator/operand set which yields a  truth value as its result (e.g. comparison operators).
  478.  
  479.  univ  ::=  item =.. item  comparison_item  ::=  item   term  comparison  ::=  comparison_item comparison_operator                      comparison_item
  480.  
  481. special  ::=  univ   comparison  predicate  ::=  name [( argument {, argument} )]                        special   built_in_predicate  predicate  ::=  ( predicate {logic_operator predicate} )
  482.  
  483. body  ::=  predicate {logic_operator predicate}  head  ::=  predicate  clause  ::=  head [:- body] .
  484.  
  485. The univ predicate was defined earlier as a built-in predicate which  is not implemented.  Its syntax is specified here since it should be  implemented if the Fuzzy Prolog interpreter is enhanced to be a  production quality tool.
  486.  
  487. Further Information
  488.  
  489.  
  490. If further information on Fuzzy Prolog is needed, there are  three possible sources:
  491.  
  492. 1)   The documents in the bibliography, especially [Richards,       1986].
  493.  
  494. 2)   The Air Force Institute of Technology, Department of       Electrical and Computer Engineering, Wright-Patterson Air       Force Base, Ohio 45433.  
  495.  
  496. 3)   The author.  Capt Bradley L. Richards may be reached at       3813 Espejo NE, Albuquerque, NM 87111.
  497.  
  498. Bibliography
  499.  
  500. Clocksin, W. F. and C. S. Mellish.  Programming in Prolog (Second  Edition).  Berlin:  Springer-Verlag, 1984.  Pereira, Fernando (editor).  C-Prolog User's Manual Version 1.2a.   SRI International, Menlo Park, California, undated.  Richards, Bradley L., Programming in Fuzzy Logic:  Fuzzy Prolog.   MS thesis.  School of Engineering, Air Force Institute of  Technology (AU), Wright-Patterson AFB, Ohio, December 1986.
  501.  
  502.